﻿using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using BFTest.Collision;
using BFTest.Services;

namespace BFTest.Ammunitions
{
    class CBulletsDGC : DrawableGameComponent, IBulletService
    {
        ICollisionService collisionService;
        ICollisionService CollisionService { get { return collisionService; } set { collisionService = value; } }

        SpriteBatch bulletsBatch;
        public SpriteBatch BulletsBatch { get { return bulletsBatch; } private set { bulletsBatch = value; } }

        // TODO: Move this to the specific ammunition types. - Booers 11/23/2011
        Texture2D bulletTexture;
        public Texture2D BulletTexture { get { return bulletTexture; } private set { bulletTexture = value; } }

        List<CBullet> bullets = new List<CBullet>();
        public List<CBullet> Bullets { get { return bullets; } private set { bullets = value; } }

        List<CBullet> bulletsToRemove = new List<CBullet>();
        public List<CBullet> BulletsToRemove { get { return bulletsToRemove; } set { bulletsToRemove = value; } }

        public CBulletsDGC(Game game)
            : base(game)
        {
            BulletsBatch = new SpriteBatch(game.GraphicsDevice);
        }

        public override void Initialize()
        {
            base.Initialize();

            CollisionService = (ICollisionService)Game.Services.GetService(typeof(ICollisionService));
            CollisionService.AddBulletList(Bullets);
        }

        protected override void LoadContent()
        {
            BulletTexture = Game.Content.Load<Texture2D>("Graphics\\pixel");
        }

        public override void Update(GameTime gameTime)
        {
            if (!BFTestGame.Battlefield.IsPaused)
            {
                for (int x = 0; x < Bullets.Count; x++)
                {
                    if (Bullets[x].Alive == false)
                    {
                        Bullets.RemoveAt(x);
                        x--;
                    }
                    else
                        Bullets[x].Update(gameTime);
                }
            }

            base.Update(gameTime);
        }

        public override void Draw(GameTime gameTime)
        {
            BulletsBatch.Begin();

            // Draw debug information
            if (BFTestGame.Battlefield.DebugShowInfo)
            {
                // Bullet count
                BulletsBatch.DrawString(BFTestGame.TooltipFont, "Bullets: " + Bullets.Count.ToString(), new Vector2(5, 5), Color.Black);
            }

            foreach (CBullet bullet in bullets)
            {
                bullet.Draw(BulletsBatch);
            }

            BulletsBatch.End();
        }

        static int id = 0;
        public int GetUniqueID()
        {
            // this method was too complicated, We'll never ever hit int.maxvalue unique entities, so this is pretty safe. - stoop
            return ++id;
        }

        public CBullet BulletFactory(BulletType type, int originID, Vector2 position, Vector2 direction, string weapon)
        {
            switch(type)
            {
                case BulletType.Rifle:
                    return new CRifle(originID, position, direction, GetUniqueID(), weapon);
                case BulletType.Rocket:
                    return new CRocket(originID, position, direction, GetUniqueID(), weapon);
                default:
                    throw new ArgumentException("type", "Invalid ammunition type.");
            }
        }

        public void DestroyBullet(int id)
        {
            foreach (CBullet bullet in Bullets)
            {
                if (bullet.ID == id)
                {
                    BulletsToRemove.Add(bullet);
                    break;
                }
            }
        }
    }
}
